package team.szm.scd.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import team.szm.scd.database.dto.CaseUploader;
import team.szm.scd.database.dto.RequestWrapper;
import team.szm.scd.database.dto.Result;
import team.szm.scd.database.entity.Case;
import team.szm.scd.database.entity.Doctor;
import team.szm.scd.database.entity.InspectionType;
import team.szm.scd.database.entity.User;
import team.szm.scd.database.vo.CaseVO;
import team.szm.scd.database.vo.MedicineVO;
import team.szm.scd.database.vo.RegisterVO;
import team.szm.scd.service.interfaces.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

@RestController
@RequestMapping("/case")
@Slf4j
public class CaseController {
    @Resource
    ILoginService loginService;
    @Resource
    ICaseService caseService;
    @Resource
    IRegisterService registerService;
    @Resource
    IInspectionService inspectionService;
    @Resource
    IMedicineService medicineService;

    @PostMapping("/all")
    @ResponseBody
    public Result<List<CaseVO>> getAllCase(@RequestBody RequestWrapper<String> userId,
                                           HttpSession session) {
        Doctor doctor = loginService.getLoginDoctor(session);
        User user = loginService.getLoginUser(session);
        if (doctor == null && user == null) {
            return Result.needLogin();
        }
        boolean hasPermission = doctor != null || user.getId().equals(userId.value);
        if (!hasPermission) {
            return Result.permissionDenied();
        }
        return Result.success(caseService.getAllCaseFromUserId(userId.value));
    }

    @PostMapping("/upload")
    @ResponseBody
    public Result<Boolean> uploadCase(@RequestBody CaseUploader uploader, HttpSession session) {
        Result<Boolean> result;
        Doctor doctor = loginService.getLoginDoctor(session);
        if (doctor == null) {
            result = Result.needLogin();
        } else {
            Case case_ = caseService.fromId(uploader.getCase_().getId());
            List<RegisterVO> list = registerService.registersDoctorHave(doctor.getId(), LocalDate.now());
            if (list.stream().noneMatch(registerVO -> registerVO.getId().equals(uploader.getCase_().getRegisterId()))) {
                result = Result.permissionDenied();
            } else {
                log.trace("upload case: " + case_);
                result = Result.success(caseService.uploadCase(uploader, LocalDateTime.now()));
            }
        }
        return result;
    }

    @PostMapping("/from_register")
    @ResponseBody
    public Result<Case> caseFromRegister(@RequestBody RequestWrapper<String> registerId,
                                         HttpSession session) {
        Doctor doctor = loginService.getLoginDoctor(session);
        if (doctor == null) {
            return Result.needLogin();
        }
        List<RegisterVO> list = registerService.registersDoctorHave(doctor.getId(), LocalDate.now());
        if (list.stream().noneMatch(r -> r.getId().equals(registerId.value))) {
            return Result.permissionDenied();
        }
        return Result.success(caseService.fromRegister(registerId.value));
    }

    @PostMapping("/get_inspections")
    @ResponseBody
    public Result<List<InspectionType>> inspectionsFromCase(@RequestBody RequestWrapper<String> caseId,
                                                            HttpSession session) {
        Result<List<InspectionType>> r;
        Doctor doctor = loginService.getLoginDoctor(session);
        if (doctor == null) {
            r = Result.needLogin();
        } else {
            Case case_ = caseService.fromId(caseId.value);
            if (case_ == null) {
                r = Result.fail((List<InspectionType>) null);
            } else {
                List<RegisterVO> list = registerService.registersDoctorHave(doctor.getId(), LocalDate.now());
                if (list.stream().noneMatch(registerVO -> registerVO.getId().equals(case_.getRegisterId()))) {
                    r = Result.permissionDenied();
                } else {
                    r = Result.success(inspectionService.fromCaseId(caseId.value));
                }
            }
        }
        return r;
    }

    @PostMapping("/set_inspections")
    @ResponseBody
    public Result<Boolean> setInspectionOfCase(@RequestBody List<String> list,
                                               HttpSession session) {
        String caseId = list.get(0);
        Doctor doctor = loginService.getLoginDoctor(session);
        if (doctor == null) {
            return Result.needLogin();
        }
        Case case_ = caseService.fromId(caseId);
        if (case_ == null) {
            return Result.fail((Boolean) null);
        }
        List<RegisterVO> voList = registerService.registersDoctorHave(doctor.getId(), LocalDate.now());
        if (voList.stream().noneMatch(r -> r.getId().equals(case_.getRegisterId()))) {
            return Result.permissionDenied();
        }
        return Result.success(caseService.updateInspectionFromId(caseId, list.subList(1, list.size())));
    }


    @PostMapping("/get_medicines")
    @ResponseBody
    public Result<List<MedicineVO>> medicinesFromCase(@RequestBody RequestWrapper<String> caseId,
                                                      HttpSession session) {
        Doctor doctor = loginService.getLoginDoctor(session);
        if (doctor == null) {
            return Result.needLogin();
        }
        Case case_ = caseService.fromId(caseId.value);
        if (case_ == null) {
            return Result.fail((List<MedicineVO>) null);
        }
        List<RegisterVO> list = registerService.registersDoctorHave(doctor.getId(), LocalDate.now());
        if (list.stream().noneMatch(r -> r.getId().equals(case_.getRegisterId()))) {
            return Result.permissionDenied();
        }
        return Result.success(medicineService.fromCaseId(caseId.value));
    }
}
